﻿#if ODIN_INSPECTOR && USING_XLUA
using UnityEngine;
using System.IO;
using static UnityEngine.Debug;
using System;
using com.susi.util;
using Sirenix.OdinInspector;

namespace com.susi.Lua {
    [Serializable, HideMonoScript]
    public class DebugerConsolePlaneByLua : MonoBehaviour {
        [Multiline(15)]
        public string Command;

        [FilePath(RequireExistingPath = true, ParentFolder = "Assets")]
        public string LuaAssetPath;

        private FileWatcher m_FileWacher;

        public bool DoLuaAssetOnWrited;

        private void Update()
        {
            if (DoLuaAssetOnWrited) {
                if (m_FileWacher == null) {
                    m_FileWacher = FileWatcher.Load(Application.dataPath.PathCombine(LuaAssetPath));
                    if (m_FileWacher != null) {
                        m_FileWacher.OnFileChangedEvent += (str) => { LuaManager.Instance?.luaEnv.DoString(str); };
                    }
                    else {
                        DoLuaAssetOnWrited = false;
                    }
                }
                else {
                    m_FileWacher?.Update();
                }
            }
            else {
                if (m_FileWacher != null) {
                    m_FileWacher.Dispose();
                    m_FileWacher = null;
                }
            }
        }

        [Button]
        private void DoCommand()
        {
            LuaManager.Instance?.luaEnv.DoString(Command);
        }

        [Button]
        private void DoLuaAsset()
        {
            var path = Application.dataPath.PathCombine(LuaAssetPath);
            if (File.Exists(path)) {
                var str = File.ReadAllText(path);
                LuaManager.Instance?.luaEnv.DoString(str);
            }
            else {
                Log($"Load fail :{path}");
            }
        }

        [Button]
        private void InstallMgr()
        {
            LuaManager.Install();
        }


        private class FileWatcher : IDisposable {
            private string              m_Path;
            private FileInfo            m_FileInfo;
            private DateTime            m_LastWriteTime;
            private float               m_InvertTime = 1f;
            private float               m_LastUpdateTime;
            public event Action<string> OnFileChangedEvent;
            private FileWatcher() { }

            public static FileWatcher Load(string path)
            {
                var fileinfo = new FileInfo(path);
                if (fileinfo.Exists) {
                    Assert(!string.IsNullOrWhiteSpace(path));
                    var fw = new FileWatcher();
                    fw.m_Path     = path;
                    fw.m_FileInfo = fileinfo;
                    return fw;
                }

                return null;
            }

            public void Dispose() { }

            public void Update()
            {
                if (Time.time - m_LastUpdateTime > m_InvertTime) {
                    m_LastUpdateTime = Time.time;
                    m_FileInfo.Refresh();
                    if (m_FileInfo.Exists && m_FileInfo.LastWriteTime > m_LastWriteTime) {
                        m_LastWriteTime = m_FileInfo.LastWriteTime;
                        OnFileChangedEvent?.Invoke(File.ReadAllText(m_Path));
                    }
                }
            }
        }
    }
}
#endif